package com.hddf.project.auth.service;

import java.security.PrivateKey;
import java.util.Map;

import org.hibernate.Session;
import org.kommii.encryption.MD5Handler;
import org.kommii.encryption.RSAHandler;
import org.kommii.mysql_conn_pool.SessionProvider;

import com.hddf.project.auth.dao.UserDao;
import com.hddf.project.auth.dao.UserDao_MongoDB;
import com.hddf.project.auth.dao_impl.UserDaoImpl;
import com.hddf.project.auth.dao_impl.UserDaoImpl_MongoDB;
import com.hddf.project.auth.pojos.User;
import org.kommii.common_utils.DateTime_Utils;
import com.kommii.mongodb_utils.Mongodb_ConnPools;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;



public class AppLoginService {
	
	private static AppLoginService login_service = null;
	private static UserDao user_dao = null;
	private static UserDao_MongoDB user_dao_mongodb = null;
	//令牌有效时间 单位是 秒 默认是 3600秒 (1小时)
	private static final long apptoken_lifetime = 60*60 ;
	static {
		if(login_service==null){
			login_service = new AppLoginService();
		}
		if(user_dao==null){
			user_dao = new UserDaoImpl();
		}
		if(user_dao_mongodb==null){
			user_dao_mongodb = new UserDaoImpl_MongoDB();
		}
	}
	
	public static AppLoginService getInstance(){
		return login_service;
	}
	
	/**
	 * 登陆成功的话返回token 并且更新令牌(token) , 不成功返回fail 或者 exception
	 * @param username passwd , valid_days 有效天数 是-1 时表示永久有效 
	 * @param passwd
	 * @return
	 */
	public String login(String username,String passwd,int valid_days,Map keypair){
		Session s = null;
		DBCollection coll  = null;
		String password = null;
		User u = null;
		int user_id = 0;
		try{
			coll = Mongodb_ConnPools.getMongoDB_Coll(User.mongodb_collection_name);
			u = user_dao_mongodb.getUserByName(username, coll);
			if(u==null){
				s = SessionProvider.getSession();
				u = user_dao.getUserByName(username, s);
				SessionProvider.commitSession(s);
				if(null!=u){
					user_dao_mongodb.save(u, coll);
				}else{
					return username+" 用户名不存在,请检查用户名!";
				}
			}
			
			if(null!=u){
				user_id = u.getId();
				password = u.getPassword();
			}
			
			String temp = MD5Handler.encrypt(passwd); 
			if(temp.equals(password)){
				long apptoken_deadline = 0;
				if(valid_days==-1){
					apptoken_deadline = -1;
				}else{
					apptoken_deadline = DateTime_Utils.getCurrentSeconds() + valid_days*24*apptoken_lifetime;
				}
				String pubk = (String)keypair.get("pubk");
				Map prik_map = (Map)keypair.get("prik_map");
				user_dao_mongodb.addAppKeyPair(user_id, pubk, prik_map, coll);
				return user_dao_mongodb.addAppToken(username, apptoken_deadline, coll);
			}else{
				return "fail";
			}
		}catch(Exception e){
			e.printStackTrace();
			SessionProvider.rollback(s);
			return "exception";
		}
	}
	
	/**
	 * 退出 将 app_token 清空 apptoken_lifetime 清零
	 * @param app_token
	 */
	public void logout(String app_token){
		
		DBCollection coll  = null;
		DBObject obj = null;
		try{
			coll = Mongodb_ConnPools.getMongoDB_Coll(User.mongodb_collection_name);
			obj = user_dao_mongodb.getUserByAppToken(app_token, coll);
			if(obj!=null){
				obj.put("app_token","");
				obj.put("apptoken_lifetime",0);
				obj.put("pubk","");
				obj.put("prik_map",null);
				user_dao_mongodb.update(obj, coll);
			}
		}catch(Exception e){
			e.printStackTrace();
			return ;
		}
	}
	
	/**
	 * 检验token 是否过期 如果过期返回null , 如果没过期返回 User 对象
	 * @param web_token
	 * @return
	 */
	public User checkAppToken(String app_token){
		DBCollection coll  = null;
		try{
			coll = Mongodb_ConnPools.getMongoDB_Coll(User.mongodb_collection_name);
			DBObject obj =  user_dao_mongodb.getUserByAppToken(app_token, coll);
			if(null!=obj){
				long apptoken_deadline = (Long)obj.get("apptoken_lifetime");
				long current = DateTime_Utils.getCurrentSeconds();
				if(apptoken_deadline==-1){
					User u = new User();
					u.toUserObject(obj);
					return u;
				}else if((current - apptoken_deadline)>=0){
					return null;
				}else{
					//obj.put("apptoken_lifetime",current+apptoken_lifetime);
					//user_dao_mongodb.update(obj, coll);
					User u = new User();
					u.toUserObject(obj);
					return u;
				}
			}else{
				return null;
			}
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
		
	}
	
	
	public User checkAppToken(String app_token,String time){
		DBCollection coll  = null;
		try{
			coll = Mongodb_ConnPools.getMongoDB_Coll(User.mongodb_collection_name);
			DBObject obj =  user_dao_mongodb.getSimpleUserByAppToken(app_token, coll);
			if(null!=obj){
				Map map = (Map)obj.get("prik_map");
				KeyPairService kps = KeyPairService.getInstance();
				PrivateKey prik = kps.getPriKeyFromMap(map);
				byte[] rs = RSAHandler.decryptDataByPriKey(time.getBytes(),prik);
				String str = new String(rs);
				long t = 0;
				try{
					t = Integer.decode(str);
				}catch(Exception e){
					t = -1;
				}
				if(t==-1){
					return null;
				}else{
					long current = DateTime_Utils.getCurrentSeconds();
					if((current - t)>60 || (current - t)<-60){
						return null;
					}
				}
				
				long apptoken_deadline = (Long)obj.get("apptoken_lifetime");
				long current = DateTime_Utils.getCurrentSeconds();
				if(apptoken_deadline==-1){
					User u = new User();
					u.toUserObject(obj);
					return u;
				}else if((current - apptoken_deadline)>=0){
					return null;
				}else{
					//obj.put("apptoken_lifetime",current+apptoken_lifetime);
					//user_dao_mongodb.update(obj, coll);
					User u = new User();
					u.toUserObject(obj);
					return u;
				}
			}else{
				return null;
			}
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
		
	}
	
	

}
